import 'dart:math';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dot_training_result_page.dart';

class DotTrainingPage extends StatefulWidget {
  @override
  _DotTrainingPageState createState() => _DotTrainingPageState();
}

class _DotTrainingPageState extends State<DotTrainingPage>
    with WidgetsBindingObserver {
  int currentQuestion = 1;
  int totalQuestions = 10; // Provide a default value
  int dotCount = 0;
  List<Offset> dotPositions = [];
  late DateTime questionStartTime;
  List<int> responseTimes = [];
  List<bool> correctness = [];
  Map<int, List<int>> numberResponseTimes = {};
  BoxConstraints?
      _dotContainerConstraints; // Store constraints for the dot drawing area

  Future<void> _loadSettings() async {
    final prefs = await SharedPreferences.getInstance();
    if (mounted) {
      setState(() {
        totalQuestions = prefs.getInt('dotTrainingQuestions') ?? 10;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _loadSettings().then((_) {
      if (_dotContainerConstraints != null && mounted && dotPositions.isEmpty) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (mounted &&
              dotPositions.isEmpty &&
              _dotContainerConstraints != null &&
              _dotContainerConstraints!.maxWidth > 0) {
            _generateNewQuestion(_dotContainerConstraints!);
          }
        });
      }
    });
  }

  @override
  void didPopNext() {
    _resetTraining(); // Reset training when returning from the results page
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('点数识别训练')),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(12.0),
            child: Text(
              '题目 $currentQuestion / $totalQuestions',
              style: TextStyle(fontSize: 20),
            ),
          ),
          Divider(),
          Expanded(
            flex: 3,
            child: ConstrainedBox(
              constraints: BoxConstraints(
                maxHeight: MediaQuery.of(context).size.height * 0.55,
                minHeight: 280, // Ensure a minimum height
              ),
              child: LayoutBuilder(
                // LayoutBuilder for the dot drawing area
                builder: (context, constraints) {
                  _dotContainerConstraints = constraints;
                  if (dotPositions.isEmpty &&
                      constraints.maxWidth > 0 &&
                      constraints.maxHeight > 0) {
                    WidgetsBinding.instance.addPostFrameCallback((_) {
                      if (mounted &&
                          dotPositions.isEmpty &&
                          _dotContainerConstraints != null &&
                          _dotContainerConstraints!.maxWidth > 0) {
                        _generateNewQuestion(_dotContainerConstraints!);
                      }
                    });
                  }
                  return Container(
                    width: double.infinity,
                    height: double.infinity,
                    decoration: BoxDecoration(
                      color: Theme.of(context).colorScheme.surfaceVariant,
                      borderRadius: BorderRadius.circular(16),
                    ),
                    child: Stack(
                      children: dotPositions
                          .map((pos) => Positioned(
                                left: pos.dx,
                                top: pos.dy,
                                child: Container(
                                  width: 24,
                                  height: 24,
                                  decoration: BoxDecoration(
                                    color:
                                        Theme.of(context).colorScheme.primary,
                                    shape: BoxShape.circle,
                                  ),
                                ),
                              ))
                          .toList(),
                    ),
                  );
                },
              ),
            ),
          ),
          Expanded(
            flex: 5,
            child: LayoutBuilder(
              builder: (context, constraints) {
                final crossAxisCount =
                    (constraints.maxWidth / 120).floor().clamp(3, 5);
                return GridView.count(
                  crossAxisCount: crossAxisCount,
                  mainAxisSpacing: 10,
                  crossAxisSpacing: 10,
                  padding: EdgeInsets.all(16),
                  childAspectRatio: 1.2,
                  children: List.generate(
                    9,
                    (i) => Container(
                      margin: EdgeInsets.all(4),
                      child: ConstrainedBox(
                        constraints: BoxConstraints(
                          minWidth: 80,
                          maxWidth: 120,
                          minHeight: 50,
                          maxHeight: 70,
                        ),
                        child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                            padding: EdgeInsets.symmetric(vertical: 8),
                            textStyle: TextStyle(fontSize: 18),
                            minimumSize: Size(60, 60),
                          ),
                          child: Text('${i + 1}'),
                          onPressed: () => _checkAnswer(i + 1),
                        ),
                      ),
                    ),
                  ),
                );
              },
            ),
          )
        ],
      ),
    );
  }

  void _generateNewQuestion(BoxConstraints drawingAreaConstraints) {
    final rand = Random();
    dotCount = rand.nextInt(9) + 1;
    dotPositions.clear();

    final double dotRadius = 12.0;
    final double containerWidth = drawingAreaConstraints.maxWidth;
    final double containerHeight = drawingAreaConstraints.maxHeight;
    final double internalPadding = 16.0;

    final double minX = internalPadding;
    final double maxX = containerWidth - internalPadding - dotRadius * 2;
    final double minY = internalPadding;
    final double maxY = containerHeight - internalPadding - dotRadius * 2;

    if (maxX <= minX || maxY <= minY) {
      print(
          'Warning: Dot drawing area is too small. Width: $containerWidth, Height: $containerHeight');
      if (mounted) setState(() {});
      return;
    }

    double adjustedMinDistance = max(40.0, dotRadius * 2.5);
    if (dotCount > 5) {
      adjustedMinDistance = max(adjustedMinDistance * 0.8, dotRadius * 2.0);
    }

    int maxAttemptsPerDot = 200;

    for (int i = 0; i < dotCount; i++) {
      bool pointPlaced = false;
      int attempts = 0;
      while (attempts < maxAttemptsPerDot && !pointPlaced) {
        final candidate = Offset(minX + rand.nextDouble() * (maxX - minX),
            minY + rand.nextDouble() * (maxY - minY));

        bool valid = true;
        for (final pos in dotPositions) {
          if ((pos - candidate).distance < adjustedMinDistance) {
            valid = false;
            break;
          }
        }

        if (valid) {
          dotPositions.add(candidate);
          pointPlaced = true;
        }
        attempts++;
      }
      if (!pointPlaced) {
        print(
            "Warning: Could not place dot $i optimally after $maxAttemptsPerDot attempts. Placing randomly.");
        // Fallback: place randomly, may overlap
        // dotPositions.add(Offset(minX + rand.nextDouble() * (maxX - minX), minY + rand.nextDouble() * (maxY - minY)));
      }
    }
    questionStartTime = DateTime.now();
    if (mounted) {
      setState(() {});
    }
  }

  void _checkAnswer(int selectedNumber) {
    final duration =
        DateTime.now().difference(questionStartTime).inMilliseconds;
    responseTimes.add(duration);
    correctness.add(selectedNumber == dotCount);

    if (!numberResponseTimes.containsKey(dotCount)) {
      numberResponseTimes[dotCount] = [];
    }
    numberResponseTimes[dotCount]!.add(duration);

    if (currentQuestion < totalQuestions) {
      currentQuestion++;
      dotPositions.clear();
      if (mounted) {
        setState(
            () {}); // This will trigger build, and LayoutBuilder will call _generateNewQuestion
      }
    } else {
      Navigator.push(
        context,
        MaterialPageRoute(
            builder: (_) =>
                DotTrainingResultPage(correctness: correctness, responseTimes: responseTimes)),
      ).then((_) {
        _resetTraining();
      });
    }
  }

  void _resetTraining() {
    currentQuestion = 1;
    responseTimes = [];
    correctness = [];
    numberResponseTimes = {};
    dotPositions.clear();
    if (mounted) {
      setState(() {});
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}
